package com.wxy.school.utils;

import com.aliyun.oss.ClientException;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.OSSException;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.aliyun.oss.model.PutObjectRequest;
import com.wxy.school.common.Constant;
import org.apache.http.entity.ContentType;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @Project: SmartCampus
 * @Package: com.wxy.common.utils
 * @Author: 王祥宇
 * @CreateTime: 2023-07-27 16:05
 * @Description: TODO
 * @Version: 1.0
 **/
public class OSSUtils {

    /**
     * @auther 王祥宇
     * @description 上传文件
     * @date 2023/7/28
     * @param: file
     * @return String
     **/
    public static String uploadFile(MultipartFile file) throws Exception {

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder()
                .build(Constant.OSS_ENDPOINT, Constant.ACCESS_KEY_ID, Constant.ACCESS_KEY_SECRET);


        // 获取文件的原名称
        String originalFilename = file.getOriginalFilename();

        // 裁剪名称，获取文件的后缀名“.jpg”
        String substring = null;
        if (originalFilename != null) {
            substring = originalFilename.substring(originalFilename.lastIndexOf("."));
        }

        // 保证文件名唯一，去掉uuid中的'-'
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String fileName = uuid + substring;

        // 把文件按日期分类，构建日期路径：avatar/2019/02/26/文件名
        Date date = new Date();
        SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd");
        String datePath = df.format(date);

        // 拼接
        fileName = datePath + "/" + fileName;

        // 创建PutObjectRequest对象。
        PutObjectRequest putObjectRequest =
                new PutObjectRequest(Constant.BUCKET_NAME, fileName, file.getInputStream());

        // 创建PutObject请求。
        ossClient.putObject(putObjectRequest);

        // 把上传后的文件url返回
        // https://wxy-smart-campus.oss-cn-hangzhou.aliyuncs.com/2023/07/27/c1c94626c3ec44aa90a037fbc9e1e3b9.png
        String url = Constant.OSS_ENDPOINT.split("//")[0] + "//" +
                Constant.BUCKET_NAME + "." + Constant.OSS_ENDPOINT.split("//")[1] + "/" + fileName;

        ossClient.shutdown();

        return url;
    }

    /**
     * @auther 王祥宇
     * @description 删除文件
     * @date 2023/7/28
     * @param: url
     * @return boolean
     **/
    public static boolean deleteFile(String url) throws OSSException {

        // 截取url，获取文件完整路径 不包括bucketName
        url = url.split(".com/")[1];

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder()
                .build(Constant.OSS_ENDPOINT, Constant.ACCESS_KEY_ID, Constant.ACCESS_KEY_SECRET);

        try {
            // 删除文件或目录。如果要删除目录，目录必须为空。
            ossClient.deleteObject(Constant.BUCKET_NAME, url);
            return true;
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    public static boolean deleteFileList(List<String> urls){

        // 创建OSSClient实例。
        OSS ossClient = new OSSClientBuilder()
                .build(Constant.OSS_ENDPOINT, Constant.ACCESS_KEY_ID, Constant.ACCESS_KEY_SECRET);

        try {
            // 删除文件。
            // 填写需要删除的多个文件完整路径。文件完整路径中不能包含Bucket名称。
            urls = urls.stream().map(url -> url.split(".com/")[1]).collect(Collectors.toList());

            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(
                    new DeleteObjectsRequest(Constant.BUCKET_NAME).withKeys(urls).withEncodingType("url"));
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
            for(String obj : deletedObjects) {
                String deleteObj =  URLDecoder.decode(obj, StandardCharsets.UTF_8);
                System.out.println(deleteObj);
            }
            return true;
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
            return false;
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    public static MultipartFile getMultipartFile(File file) {
        MultipartFile multipartFile = null;
        try {
            multipartFile = new MockMultipartFile(file.getName(),file.getName(),
                    ContentType.APPLICATION_OCTET_STREAM.toString(),new FileInputStream(file));
        } catch (IOException e) {
            e.printStackTrace();
        }
        return multipartFile;
    }
}
